package com.xu.sso.web.service.impl;

import com.xu.sso.core.enums.ErrorMessage;
import com.xu.sso.core.exception.SSOException;
import com.xu.sso.core.model.BaseResponse;
import com.xu.sso.core.utils.ExceptionUtil;
import com.xu.sso.db.model.base.App;
import com.xu.sso.db.model.base.AppRole;
import com.xu.sso.db.service.ApiAuthDBService;
import com.xu.sso.db.service.AppDBService;
import com.xu.sso.db.service.ResourcesDBService;
import com.xu.sso.db.service.RoleDBService;
import com.xu.sso.web.model.request.AddAppRequest;
import com.xu.sso.web.model.request.AppSearchRequest;
import com.xu.sso.web.model.request.ChangeAppRequest;
import com.xu.sso.web.service.AppService;
import com.xu.sso.web.service.convert.AppConvert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class AppServiceImpl implements AppService {

    @Autowired
    private AppDBService appDBService;
    @Autowired
    private RoleDBService roleDBService;
    @Autowired
    private ResourcesDBService resourcesDBService;
    @Autowired
    private ApiAuthDBService apiAuthDBService;

    @Override
    public List<App> findAllApp() {
        return appDBService.findAllApps();
    }

    @Override
    public List<App> findAllStartWebApp() {
        return appDBService.findAllStartWebApp();
    }

    @Override
    public List<App> findAllServerApp() {
        return appDBService.findAllServerApp();
    }

    @Override
    public List<App> findAllStartApp() {
        return appDBService.findAllStartApps();
    }

    @Override
    public List<App> findAllAppByUser(String username) {
        return appDBService.findAllUserApps(username);
    }

    @Override
    public List<App> findAllAppByLeader(String username) {
        return appDBService.findAllAppByLeader(username);
    }

    @Override
    public List<App> findAppList(AppSearchRequest request) {
        App app = AppConvert.convert(request);
        return appDBService.findApps(app);
    }

    @Override
    public App findAppByAppId(String appId) {
        return appDBService.findAppByAppId(appId);
    }

    @Override
    public BaseResponse checkAppExist(String appId) throws SSOException {
        App app = appDBService.findAppByAppId(appId);
        if (null != app) {
            throw ExceptionUtil.createException(ErrorMessage.AppExist);
        }
        return new BaseResponse();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseResponse createApp(AddAppRequest request, String username) throws SSOException {
        App app = appDBService.findAppByAppId(request.getAppId());
        if (null != app) {
            log.info(">>>>>>>>>>>>>>>add app [{}] is exist...", request.getAppId());
            throw ExceptionUtil.createException(ErrorMessage.AppExist);
        }
        // 创建APP
        app = AppConvert.convert(request, username);
        int i = appDBService.createApp(app);
        if (i != 1) {
            log.info(">>>>>>>>>>>>>>>add app [{}] error...", request.getAppId());
            throw ExceptionUtil.createException(ErrorMessage.AddAppDataError);
        }
        // 添加操作人权限
        i = appDBService.createAppUser(request.getAppId(), username);
        if (i != 1) {
            log.info(">>>>>>>>>>>>>>>add appUser [{}] error...", request.getAppId());
            throw ExceptionUtil.createException(ErrorMessage.AddAppUserError);
        }
        return new BaseResponse();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseResponse deleteAppUser(String appId, String username) throws SSOException {
        // 删除AppUserRole
        roleDBService.deleteAppUserRolesByAppUser(appId, username);
        // 删除AppUser
        int i = appDBService.deleteAppUser(username, appId);
        if (i != 1) {
            log.info(">>>>>>>>>>>>>>>>>delete App [{}] User [{}] error...", appId, username);
            throw ExceptionUtil.createException(ErrorMessage.DeleteAppUserError);
        }
        return new BaseResponse();
    }

    @Override
    public BaseResponse checkLeader(String appId, String username) throws SSOException {
        App app = appDBService.findAppByAppId(appId);
        if (null == app) {
            throw ExceptionUtil.createException(ErrorMessage.NoAppError);
        }
        String leaders = app.getLeader();
        if (leaders.contains(";")) {
            String[] ls = leaders.split(";");
            long count = Arrays.stream(ls).filter(l -> l.equals(username)).count();
            if (count == 0) {
                throw ExceptionUtil.createException(ErrorMessage.NotLeader);
            }
        } else if (!leaders.equals(username)) {
            throw ExceptionUtil.createException(ErrorMessage.NotLeader);
        }
        return new BaseResponse();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseResponse changeStatus(String appId, String status, String username) throws SSOException {
        checkLeader(appId, username);
        int i = appDBService.changeStatus(appId, status);
        if (i != 1) {
            log.info(">>>>>>>>>>>>>update app [{}] [{}] error...", appId, status);
            throw ExceptionUtil.createException(ErrorMessage.UpdateAppError);
        }
        return new BaseResponse();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseResponse changeApp(ChangeAppRequest request) throws SSOException {
        App app = AppConvert.convert(request);
        int i = appDBService.updateApp(app);
        if (i != 1) {
            log.info(">>>>>>>>>>>>>update app [{}] error...", request.getAppId());
            throw ExceptionUtil.createException(ErrorMessage.UpdateAppError);
        }
        apiAuthDBService.updateApiAppName(request.getAppId(), request.getAppName());
        if (!request.getOldAppId().equals(request.getAppId())) {
            // 更新 AppUser

            // 更新 AppRole

            // 更新 AppUserRole

            // 更新 resources

            // 更新 resources_role
        }
        return new BaseResponse();
    }

    @Override
    public List<AppRole> findAppRoles(String appId) {
        return roleDBService.findRolesByApp(appId);
    }

    @Override
    public boolean isLeader(String appId, String username) {
        App app = appDBService.findAppByAppId(appId);
        if (null == app) {
            return false;
        }
        String leaders = app.getLeader();
        if (leaders.contains(";")) {
            String[] ls = leaders.split(";");
            long count = Arrays.stream(ls).filter(l -> l.equals(username)).count();
            if (count > 0) {
                return true;
            }
        } else if (leaders.equals(username)) {
            return true;
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BaseResponse deleteApp(String appId) throws SSOException {
        // 删除 AppUser
        appDBService.deleteAllAppUserByApp(appId);
        // 删除 AppRole
        roleDBService.deleteAppRoleByApp(appId);
        // 删除 AppUserRole
        roleDBService.deleteAppUserRolesByApp(appId);
        // 删除 resources
        resourcesDBService.deleteResourcesByApp(appId);
        // 删除 resources_role
        roleDBService.deleteResourcesRoleByAppId(appId);
        // 删除 api_auth
        apiAuthDBService.deleteApiAuthByAppId(appId);
        // 删除 APP
        int i = appDBService.deleteApp(appId);
        if (i != 1) {
            throw ExceptionUtil.createException(ErrorMessage.DeleteAppError);
        }
        return new BaseResponse();
    }

}
